package org.destiny;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;

@Service
public class StudentService {

    @Autowired
    private StudentDslRepository studentDslRepository;

    @PersistenceContext
    private EntityManager entityManager;

    private JPAQueryFactory queryFactory;

    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }

    /**
     * 查询所有
     * 
     * @return
     */
    public List<StudentPO> findAll() {
        QStudentPO qStudentPO = QStudentPO.studentPO;
        return queryFactory.selectFrom(qStudentPO).fetch();
    }

    /**
     * 该例是使用spring data QueryDSL实现
     * 
     * @param userName
     * @return
     */
    public StudentPO queryByUserName(String userName) {
        QStudentPO qStudent = QStudentPO.studentPO;
        Predicate predicate = qStudent.userName.eq(userName);
        return studentDslRepository.findOne(predicate);
    }

    /**
     * 单表单条件查询
     * 
     * @param userName
     * @return
     */
    public StudentPO queryDslByUserName(String userName) {
        QStudentPO qStudent = QStudentPO.studentPO;
        return queryFactory.selectFrom(qStudent).where(qStudent.userName.eq(userName)).fetchOne();
    }

    /**
     * 单表单条件查询
     * 
     * @param userName
     * @return
     */
    public StudentPO queryDslByUserName(String userName, String school) {
        QStudentPO qStudent = QStudentPO.studentPO;
        Predicate predicate = qStudent.userName.eq(userName).and(qStudent.school.eq(school));
        StudentPO student = studentDslRepository.findOne(predicate);
        return student;
    }

    /**
     * 关联查询所有
     * 
     * @return
     */
    public List<StudentPO> queryStudentAllByJoin() {
        QStudentPO qStudentPO = QStudentPO.studentPO;
        QStudentPO userName = new QStudentPO("userName");
        return queryFactory.selectFrom(qStudentPO).innerJoin(qStudentPO).on(qStudentPO.id.eq(userName.id)).fetch();
    }

    /**
     * 排序
     * 
     * @return
     */
    public List<StudentPO> queryStudentListOrder() {
        QStudentPO qStudentPO = QStudentPO.studentPO;
        return queryFactory.selectFrom(qStudentPO).orderBy(qStudentPO.id.desc()).fetch();
    }

    /**
     * groupBy
     * 
     * @return
     */
    public List<String> queryStudentsGroupBy() {
        QStudentPO qStudentPO = QStudentPO.studentPO;
        return queryFactory.select(qStudentPO.school).from(qStudentPO).groupBy(qStudentPO.school).fetch();
    }

    /**
     * 保存操作
     * 
     * @param student
     * @return
     */
    public StudentPO save(StudentPO student) {
        return studentDslRepository.save(student);
    }

    /**
     * 根据名称删除,需要开启事务
     * 
     * @param userName
     * @return
     */
    @Transactional
    public Long deleteStudent(String userName) {
        QStudentPO qStudentPO = QStudentPO.studentPO;
        return queryFactory.delete(qStudentPO).where(qStudentPO.userName.eq(userName)).execute();
    }

    /**
     * 根据id更新操作
     * 
     * @param student
     * @param id
     * @return
     */
    @Transactional
    public Long updateStudentById(StudentPO student, Long id) {
        QStudentPO qStudentPO = QStudentPO.studentPO;
        return queryFactory.update(qStudentPO).where(qStudentPO.id.eq(id))
                .set(qStudentPO.userName, student.getUserName()).set(qStudentPO.age, student.getAge()).execute();

    }

    /**
     * 原生的Query
     * 
     * @param userName
     * @return
     */
    public StudentPO nativeQueryStudentByUserName(String userName) {
        QStudentPO qStudentPO = QStudentPO.studentPO;
        Query query = queryFactory.selectFrom(qStudentPO).where(qStudentPO.userName.eq(userName)).createQuery();
        return (StudentPO) query.getSingleResult();
    }

    /**
     * 分页查询
     * 
     * @param curPageNum
     * @param pageSize
     * @return
     */
    public Page<StudentPO> queryStudentsPaged(Integer curPageNum, Integer pageSize) {
        Predicate predicate = QStudentPO.studentPO.id.lt(10);
        PageRequest pageable = new PageRequest(curPageNum, pageSize);
        return studentDslRepository.findAll(predicate, pageable);
    }

}
